﻿using System;
using System.Drawing;
using System.Threading;

namespace Ue.Components.Snap
{
    public class WebPreviewFactory
    {
        #region static GetWebPreview

        public static Bitmap GetWebPreview(Uri uri)
        {
            return new WebPreviewFactory(uri)
                .GetWebPreview();
        }
        public static Bitmap GetWebPreview(Uri uri, int timeout, int width, int height, bool isFullPage)
        {
            return new WebPreviewFactory(uri, timeout, width, height, isFullPage)
                .GetWebPreview();
        }

        #endregion

        private Uri crawlUri = null;
        private Exception exception = null;
        private Bitmap bitmap = null;
        private int timeout = 30 * 1000;    //设置线程超时时长
        private int width = 200;            //缩图宽
        private int height = 150;           //缩图高
        private bool isFullPage = true;

        private WebPreviewFactory(Uri uri)
            : this(uri, 30 * 1000, 200, 150, true) { }

        private WebPreviewFactory(Uri crawlUri, int timeout, int width, int height, bool isFullPage)
        {
            this.crawlUri = crawlUri;
            this.timeout = timeout;
            this.width = width;
            this.height = height;
            this.isFullPage = isFullPage;
        }

        internal Bitmap GetWebPreview()
        {
            //Asp.Net引用Winform（类似ActiveX）控件，必须开单线程
            var thread = new Thread(new ParameterizedThreadStart(StaRun));
            thread.SetApartmentState(ApartmentState.STA);
            thread.Start(this);

            if (!thread.Join(timeout))
            {
                thread.Abort();
                throw new TimeoutException();
            }

            if (exception != null)
            {
                throw exception;
            }

            if (bitmap == null)
            {
                throw new ExecutionEngineException();
            }

            return bitmap;
        }

        /// <summary>
        /// 为WebBrowser所开线程的启动入口函数，相当于Winform里面的Main()
        /// </summary>
        /// <param name="_wp"></param>
        private static void StaRun(object webPreviewFactory)
        {
            var wp = webPreviewFactory as WebPreviewFactory;
            try
            {
                var webPreview = new WebPreview(wp.crawlUri, wp.width, wp.height, wp.isFullPage);
                wp.bitmap = webPreview.GetWebPreview();
            }
            catch (Exception ex)
            {
                wp.exception = ex;
            }
        }
    }
}
